home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / MPW Interfaces & Libraries / AStructMacs / Sample.a < prev    next >
Encoding:
Text File  |  1992-01-29  |  16.5 KB  |  452 lines  |  [TEXT/MPS ]

  1.                 TITLE            'Sample - A small sample application using Structured Macros'
  2.                 
  3. * File Sample.a using structured program macros
  4. * Copyright Apple Computer, Inc. 1985, 1986, 1987, 1988, 1989, 1990
  5. * All rights reserved.
  6.  
  7. * Sample -- A small sample application written in MPW Assembler.  It displays
  8. * single, fixed-size window in which the user can enter and edit text.
  9.  
  10. * This is a translation of the Sample.a program in the Inside Macintosh
  11. * documentaion.  Some changes were made to illustrate some of the features of
  12. * the MPW Assembler, but most comments and the order of the code is the same as
  13. * the Pascal example.
  14.  
  15. * Note, this code assumes that the DEGUG switch available to the structured
  16. * macros is OFF (the preset case), since DoCommand pops its return and
  17. * parameter directly off the stack and doesn't know that with DEBUG set a
  18. * LINK on A6 is generated!
  19.  
  20. * The PRINT directive turns off listing (if a listing is being generated using
  21. * -l command line option) of the standard include files.  The INCLUDEs bring in
  22. * the equate and trap definitions needed by Sample.  We could use the LOAD/DUMP
  23. * facilities on these includes if we intended to assemble this program over and
  24. * over again, but that would confuse the example here.
  25.  
  26.                 PRINT            OFF
  27.                 INCLUDE     'Traps.a'
  28.                 INCLUDE     'ToolEqu.a'
  29.                 INCLUDE     'QuickEqu.a'
  30.                 INCLUDE     'SysEqu.a'
  31.                 LOAD            'ProgStrucMacs.d'
  32.                 LOAD            'FlowCtlMacs.d'
  33.                 PRINT            ON,NOGEN
  34.  
  35.  
  36.                 TITLE            'Global Declarations for Sample'
  37.  
  38. *************
  39. * Constants *
  40. *************
  41.  
  42. appleID             EQU             128         ; Resource IDs/menu IDs for Apple,
  43. fileID                EQU             129         ;     File, and Edit menus
  44. editID                EQU             130
  45.  
  46. menuCount            EQU             3                ; Total number of menus
  47.  
  48. windowID            EQU             128         ; Resource ID for application'w window
  49.  
  50. undoCommand     EQU             1                ; Menu item numbers identifying
  51. cutCommand        EQU             3                ; commands in Edit menu
  52. copyCommand     EQU             4
  53. pasteCommand    EQU             5
  54. clearCommand    EQU             6
  55.  
  56. aboutMeDLOG     EQU             128         ; Resource ID for the "about" dialog
  57.  
  58. authorItem        EQU             2                ; "About sample" dialog item numbers
  59. languageItem    EQU             3
  60.  
  61.  
  62. *********
  63. * Types *
  64. *********
  65.  
  66. * To illustrate how the template type feature works the following templates are
  67. * declared and used instead of the simple offsets defined in the equate files.
  68. * By using these, the Assember source appromixates very closely the Pascal
  69. * source for referencing the corresponding information.  Perhaps someday we will
  70. * have a set of "equate" files that define types just like Pascal USES units do!
  71.  
  72. Point                    RECORD        0                ; Point = RECORD CASE INTEGER OF
  73. v                            DS.W            1                ;                  1: (v: INTEGER;
  74. h                            DS.W            1                ;                            h: INTEGER);
  75.                             ORG             v                ;                    2: (vh: ARRAY[1..2] OF INTEGER)
  76. vh                        DS.L            1
  77.                             ENDR                            ;                    END;
  78.  
  79. Rect                    RECORD        0                ; Rect  = RECORD CASE INTEGER OF
  80. top                     DS.W            1                ;                    1: (top:    INTEGER;
  81. left                    DS.W            1                ;                            left:   INTEGER;
  82. bottom                DS.W            1                ;                            bottom: INTEGER;
  83. right                    DS.W            1                ;                            right:  INTEGER);
  84.                             ORG             top            ;
  85. topLeft             DS.L            Point        ;                    2: (topLeft:  Point;
  86. botRight            DS.L            Point        ;                    3: (botRight: Point)
  87.                             ENDR                            ;                  END;
  88.  
  89. BitMap                RECORD        0                ;  BitMap = RECORD
  90. baseAddr            DS.L            1                ;                      baseAddr: QDPtr;
  91. rowBytes            DS.W            1                ;                      rowBytes: INTEGER;
  92. bounds                DS.L            Rect        ;                          bounds:    Rect
  93.                             ENDR                            ;                    END;
  94.  
  95. EventRecord     RECORD        0                ; EventRecord = RECORD
  96. what                    DS.W            1                ;                          what:      INTEGER;
  97. message             DS.L            1                ;                          message:     LONGINT;
  98. when                    DS.L            1                ;                          when:      LONGINT;
  99. where                    DS.L            Point        ;                          where:         Point;
  100. modifiers            DS.W            1                ;                          modifiers: INTEGER
  101.                             ENDR                            ;                        END;
  102.  
  103.                 EJECT
  104.  
  105. ***********************
  106. * QuickDraw's Globals *
  107. ***********************
  108.  
  109. * The following data module is used to define the QuickDraw global data area.
  110. *                -----------
  111.  
  112. QuickDraw            RECORD        ,DECREMENT
  113. thePort             DS.L            1
  114. white                    DS.B            8
  115. black                    DS.B            8
  116. gray                    DS.B            8
  117. ltGray                DS.B            8
  118. dkGray                DS.B            8
  119. arrow                    DS.B            cursRec
  120. screenBits        DS.B            BitMap
  121. randSeed            DS.L            1
  122.                             ORG             -grafSize
  123.                             ENDR
  124.  
  125.  
  126. **************************
  127. * Global Data for Sample *
  128. **************************
  129.  
  130. * This is the global data used by Sample.  Both these and the QuickDraw data
  131. * above are referenced through a WITH statetment at the beginning of the procs
  132. * that use this data. Since the Assembler knows when it is referencing data
  133. * in a data module (since they must be declared before they are accessed),
  134. * and since such data can only be accessed based on A5, there is no need to
  135. * explicitly specify A5 in any code which references the data (unless indexing
  136. * is used).  Thus, in this program we have omitted all A5 references when
  137. * referencing the data.
  138.  
  139. GlobalData        RECORD
  140. appleMenuH        DS.L            1                            ; Handle to the Apple menu
  141. fileMenuH            DS.L            1                            ; Handle to the File menu
  142. editMenuH            DS.L            1                            ; Handle to the Edit menu
  143. dragRect            DS.L            Rect                    ; Drag limits
  144. txRect                DS.L            Rect                    ; TextEdit's limits
  145. doneFlag            DS.B            1                            ; True if Quit command processed
  146. myEvent             DS.L            EventRecord     ; Current event info
  147. wRecord             DS.B            windowSize        ; The application window record
  148. myWindow            DS.L            1                            ; Ptr to the application window
  149. whichWindow     DS.L            1                            ; Current event's window
  150. textH                    DS.L            1                            ; TextEdit's text handle
  151. mousePt             DS.L            Point                    ; Used to get current mouse point
  152. iBeamHdl            DS.L            1                            ; Handle to the iBeam cursor
  153.                             ENDR
  154.  
  155.  
  156.                 TITLE            'SetupMenus - Set up menus and menu bar'
  157.  
  158. ******************************************
  159. * SetUpMenus - Set up menus and menu bar *
  160. ******************************************
  161.  
  162. * This is a code module used only during initialization.  Note, just as in the
  163. * Pascal version, this is a distinct code module.  Also, since SetUpMenus is
  164. * only called during initialization, there is no need to keep it loaded.  So
  165. * we will place SetUpMenus in its own segment (called "Initialize") and unload
  166. * it after SetUpMenus returns.
  167.  
  168.     SEG  'Init'                                                ; This illustrates segmenting!
  169.   PROCEDURE SetUpMenus
  170.             
  171.         BEGIN With=GlobalData
  172.             Call _GetRMenu:L(#appleID),(Pass,appleMenuH); Read Apple menu from rsrc file
  173.             Call _InsertMenu((A7):L, #0)    ; Install Apple menu in menu bar
  174.             Call _AddResMenu(, #'DRVR':L)    ; Add DA names to Apple menu
  175.             
  176.             Call _GetRMenu:L(#fileID),(Pass,fileMenuH); Read File menu from rsrc file
  177.             Call _InsertMenu(, #0)                ; Install File menu in menu bar
  178.             
  179.             Call _GetRMenu:L(#editID),(Pass,editMenuH); Read Edit menu from rsrc file
  180.             Call _InsertMenu(, #0)                ; Install Edit menu in menu bar
  181.             
  182.             Call _DrawMenuBar                            ; Draw the menu bar
  183.             Return                                                ; Exit
  184.         ENDP
  185.  
  186.  
  187.                 TITLE            'ShowAboutMeDialog - Display the "About"...'
  188.  
  189. **********************************************
  190. * ShowAboutMeDialog - Display the "About"... *
  191. **********************************************
  192.  
  193. * This procedure is called from DoCommand when item #1 is selected from the
  194. * apple menu list.    It sets up a dialog box indicating the author and language
  195. * of this sample program.  The box remains until the user clicks the mouse on
  196. * the continue button.
  197.  
  198.     SEG                                                             ; Undo SEG done above
  199.     PROCEDURE ShowAboutMeDialog
  200.                 
  201.         VAR savePort: L,                          \    ; Port at the time of call
  202.                 itemType: W,                          \    ; Returned by _GetDItem (not used)
  203.                 itemHdl:  L,                            \    ; Handle to the item
  204.                 itemRect: Rect,                      \    ; Returned by _GetDItem (not used)
  205.                 itemHit:  W                                ; Part code
  206.                 
  207.         BEGIN Save=A3
  208.           theDialog: EQU A3                            ; Dialog pointer
  209. *
  210. *         Start here: create  current grafPort, and allocate space for the dialog box
  211. *
  212.             Call _GetPort(savePort(FP):A)    ; Remember the current grafPort
  213.             Call _GetNewDialog:A(#aboutMeDLOG, NIL, -1:A)    ;Create a new dialog
  214.             MOVE.L    (A7),theDialog                ; theDialog holds ptr to dialog info
  215.             Call _SetPort                                    ; Set the current grafPort
  216. *
  217. *         Fill in the dialog box with the proper author and language
  218. *
  219.             Call _GetDItem(theDialog:L, #authorItem, itemType(FP):A, itemHdl(FP):A, \
  220.                                         itemRect(FP):A); Get dialog's author item info
  221.             Call _SetIText(itemHdl(FP):L, #'Nebur L. Ari':A); Update the author item
  222.             
  223.             Call _GetDItem(theDialog:L, #languageItem, itemType(FP):A, itemHdl(FP):A, \
  224.                                         itemRect(FP):A); Get dialog's language info
  225.             Call _SetIText(itemHdl(FP):L, #'Assembler':A); Update the language item
  226. *
  227. *         Wait for user to click the continue button
  228. *
  229.             REPEAT#    
  230.                 Call _ModalDialog(NIL, itemHit(FP):A)    ; Wait for the click...
  231.             UNTIL#.S itemHit(FP) EQ #okButton
  232. *
  233. *         User is now satisfied -- let's get out of here!
  234. *
  235.             Call _CloseDialog(theDialog:L); Close the dialog box
  236.             Call _SetPort(savePort(FP):L)    ; Put original grafPort back
  237.             Return
  238.         ENDP
  239.  
  240.  
  241.                 TITLE            'DoCommand - Execute a menu command'
  242.  
  243. ***********************************************************************
  244. * DoCommand - Execute command specified by the result of a MenuSelect *
  245. ***********************************************************************
  246.  
  247. * This is another code module which takes as a parameter the MenuSelect return
  248. * value.  It is next to the top of the stack just before the return address.
  249.  
  250.     PROCEDURE DoCommand;
  251.     
  252.         BEGIN With=GlobalData
  253.             return:  EQU A6                                ; The return address will be in A6
  254.             mResult: EQU D3                                ; mResult will be kept in D3
  255.             theItem: EQU mResult                     ; LoWord(mResult) is mResult treated as a word
  256.  
  257. *         The following defines some local data known only to this proc.
  258.  
  259.             DATA                                                    ; Switch into local data section
  260.             name: DS.B    256                             ; Desk accessory name string
  261.             CODE                                                    ; Switch back to code section
  262.  
  263.             MOVEA.L    (A7)+,return                    ; Pop return into A6
  264.             MOVE.L    (A7)+,mResult                    ; Pop mResult parameter
  265.             
  266.             MOVE.L    mResult,D0                        ; Case on menu ID in
  267.             SWAP        D0                                        ;    high-order word of mResult
  268.  
  269.             Switch#    D0
  270.                 Case#.S appleID                            ; Apple menu processing
  271.                     Call _GetItem(appleMenuH:L, theItem, name:A); Get DA name
  272.                     IF# theItem EQ #1 THEN.S
  273.                         Call ShowAboutMeDialog
  274.                     ELSE#.S
  275.                         Call _OpenDeskAcc:W(name:A),Pop
  276.                     ENDIF#
  277.                     Call _SetPort(myWindow:L); Restore app window as grafPort
  278.                     Leave#.S                                ;  Exit
  279.  
  280.                 Case#.S fileID                        ; File menu processing
  281.                     ST doneFlag                            ; Set flag to Quit (caller tests)
  282.                     Leave#.S                                ; Exit
  283.  
  284.                 Case#.S editID                        ; Edit menu processing
  285.                     MOVE theItem,D1                    ; if DA window is the active window
  286.                     SUBQ #1,D1                            ; SystemEdit requires item adjustment
  287.                     Call _SysEdit:B(D1),CC    ; Call Desk Mgr to handle editing command
  288.                                                                     ; if DA window is the active window
  289.                     IF# EQ THEN.S                        ; App window is active window
  290.                         Switch# theItem                ; Case on menu item (command) number
  291.                             Case#.S cutCommand; Call TextEdit to handle command
  292.                                 Call _TECut(textH:L)
  293.                                 Leave#.S
  294.                             Case#.S copyCommand
  295.                                 Call _TECopy(textH:L)
  296.                                 Leave#.S
  297.                             Case#.S pasteCommand
  298.                                 Call _TEPaste(textH:L)
  299.                                 Leave#.S
  300.                             Case#.S clearCommand
  301.                                 Call _TEDelete(textH:L)
  302.                         EndS#                                ; of item case
  303.                     ENDIF#
  304.             EndS#                                            ; of editID case
  305.                 
  306.             Call _HiliteMenu(#0)            ; Unhighlight menu item
  307.             JMP (return)                            ; Exit
  308.         ENDP
  309.  
  310.                  TITLE            'Sample - Main Program'
  311.  
  312. ***********************************************
  313. * Sample Main Program - Execution starts here *
  314. ***********************************************
  315.  
  316. * This is another code module.    It is declared as the main code module which
  317. * means execution will start here.
  318.  
  319.     PROCEDURE Sample,Main=Y
  320.         
  321.         BEGIN With=(QuickDraw,GlobalData)    ;  Cover our data areas
  322. *
  323. *         Initialization
  324. *
  325.             Call _InitGraf(thePort:A)    ; Initialize QuickDraw
  326.             Call _InitFonts                        ; Initialize Font Manager
  327.             MOVE.L    #$0000FFFF,D0            ; Discard any previous events
  328.             Call _FlushEvents                    ; FlushEvents(EventEvent, 0);
  329.             Call _InitWindows                    ; Initialize Window Manager
  330.             Call _InitMenus                        ; Initialize Menu Manager
  331.             Call _TEInit                             ; Initialize TextEdit
  332.             Call _InitDialogs(NIL)        ; Initialize Dialog Manager
  333.             Call _InitCursor                     ; Make cursor an arrow
  334.             
  335.             Call _GetCursor:L(#iBeamCursor),iBeamHdl; Get the iBeam cursor handle to
  336.                                                                                             ; use in the main ctl loop when
  337.                                                                                             ; cursor is in the window
  338.  
  339.             Call SetUpMenus                        ; Set up menus and menu bar
  340.             Call _UnLoadSeg(SetUpMenus:A)    ; Unload the SetUpMenus segment since we
  341.                                                                         ; will never call it again
  342.             
  343.             WITH    screenBits.bounds            
  344.             MOVE       right,D0                    ; Call QuickDraw to set dragging
  345.             SUBQ      #4,D0                            ; boundaries; ensure at least
  346.             MOVE      bottom,D1                    ; 4 by 4 pixels will remain visible
  347.             SUBQ      #4,D1
  348.             Call _SetRect(dragRect:A, #4, #24, D0, D1)
  349.             ENDWITH
  350.             
  351.             CLR.B        doneFlag                    ; Flag to detect Quit command
  352.             
  353.             Call _GetNewWindow:L(#windowID, wRecord:A, #-1:L),(Pass,myWindow); Put up app window
  354.             Call _SetPort()                        ; Set current grafPort to this window
  355.             MOVE.L    thePort,A0                ; Rectangle for text in window
  356.             MOVE.L    portRect+topLeft(A0),txRect.topLeft
  357.             MOVE.L    portRect+botRight(A0),txRect.botRight
  358.             Call _InSetRect(txRect:A, #4, #0)                ; Bring it in 4 pixels from left/right edges
  359.             Call _TENew:L(txRect:A, txRect:A),textH    ; Prepare for receiving text
  360.  
  361.                 EJECT
  362. *
  363. *         Main Event Loop
  364. *
  365.             REPEAT# 
  366.                 Call _SystemTask                     ; Perform periodic actions defined for DAs
  367.  
  368.                 Call _FrontWindow:L,D0        ; Get ptr to the front window
  369.                 IF# D0 EQ.L myWindow THEN.S    ; Front window is my mindow
  370.                     Call _GetMouse(mousePt:A); Is mouse pointing in my window ?
  371.                     MOVEA.L     myWindow,A0
  372.                     Call _PtInRect:B(mousePt:L, portRect(A0):A),CC
  373.                     IF# NE THEN.S                        ; Yes, use the iBeam cursor
  374.                         MOVE.L    iBeamHdl,A0
  375.                         MOVE.L    (A0),-(A7)
  376.                     ELSE#.S                                    ; No, use the arrow cursor
  377.                         PEA     arrow
  378.                     ENDIF#
  379.                     Call _SetCursor                    ; Set cursor to arrow or iBeam
  380.                     Call _TEIdle(textH:L)        ; Make vertical bar blink
  381.                 ENDIF#
  382.  
  383.                 Call _GetNextEvent:B(#everyEvent, myEvent:A),CC; ToolBox Event Mgr
  384.                 IF# NE THEN
  385.                     Switch# myEvent.what,JmpTbl=Y,ChkRng=Y; Case on event type
  386.                         Case# mButDwnEvt            ; Mouse down event processing
  387.                             Call _FindWindow:W(myEvent.where:L, whichWindow:A),D0
  388.                             Switch# D0                    ; Process according to where
  389.                                 Case#.S inMenuBar    ; Menu bar: process command
  390.                                     Call _MenuSelect:L(myEvent.where:L)
  391.                                     Call DoCommand    ; DoCommand(MenuSelect(myEvent.where));
  392.                                     Leave#.S
  393.                                 
  394.                                 Case#.S inSysWindow    ; Desk accessory window
  395.                                     Call _SystemClick(myEvent:A, whichWindow:L)
  396.                                     Leave#.S
  397.                                     
  398.                                 Case#.S inDrag        ; Title bar
  399.                                     Call _DragWindow(whichWindow:L, myEvent.where:L, dragRect:A)
  400.                                     Leave#.S
  401.                                     
  402.                                 Case#.S inContent    ; Body of application window
  403.                                     Call _FrontWindow:L,D0                 ; Which is in front?
  404.                                     IF# D0 NE.L whichWindow THEN.S    ; Not us!
  405.                                         Call _SelectWindow(whichWindow:L)
  406.                                     ELSE#.S                                                ; If we are in front...
  407.                                         Call _GlobalToLocal(myEvent.where:A)
  408.                                         MOVE.L    myEvent.where,-(A7)   
  409.                                         MOVE        myEvent.modifiers,D0
  410.                                         BTST        #shiftKey,D0
  411.                                         SNE         -(A7)                                ; Indicate if shift key is down
  412.                                         Call _TEClick(,,textH:L)
  413.                                     ENDIF#
  414.                             EndS#
  415.                             Leave#
  416.                         
  417.                         Case# keyDwnEvt,autoKeyEvt    ; Key down and Auto key event processing
  418.                             BTST        #CmdKey,myEvent.modifiers
  419.                             IF# NE THEN.S                ; If cmd key down, call Menu Mgr to learn which
  420.                                 Call _MenuKey:L(myEvent.message+2)
  421.                                 Call DoCommand        ; Process the command key
  422.                             ELSE#.S                            ; If not a command key...
  423.                                 Call _TEKey(myEvent.message+2, textH:L); ...pass char to TE
  424.                             ENDIF#
  425.                             Leave#.S
  426.                         
  427.                         Case# activateEvt            ; Activate/deactivate event processing
  428.                             MOVE        myEvent.modifiers,D0; App window status changed
  429.                             BTST        #activeFlag,D0            ; Is app window becoming active ?
  430.                             IF# NE THEN.S                                ; Yes
  431.                                 Call _TEActivate(textH:L)    ; Call TE to highlight selection and
  432.                                 Call _DisableItem(editMenuH:L, #undoCommand); disable UnDo
  433.                             ELSE#.S                                            ; App window is becoming inactive
  434.                                 Call _TEDeactivate(textH:L); Unhighlight selection and
  435.                                 Call _EnableItem(editMenuH:L, #undoCommand); enable UnDo
  436.                             ENDIF#
  437.                             Leave#.S
  438.                             
  439.                         Case# updatEvt                ; Update event processing
  440.                             Call _BeginUpDate(myEvent.message:L)        ; Window needs updating
  441.                             MOVEA.L    thePort,A3                                            ; We need thePort^.portRect
  442.                             Call _EraseRect(portRect(A3):A)                    ; Call QD to erase text area
  443.                             Call _TEUpdate(portRect(A3):A, textH:L)    ; Call TE to update the text
  444.                             Call _EndUpDate(myEvent.message:L)            ; End update
  445.                     ENDS#
  446.                 ENDIF#
  447.                     
  448.                 TST.B    doneFlag
  449.             UNTIL# NE
  450.             Return
  451.         END                                                                 ; of Sample
  452.